package utils

import (
	"github.com/pkg/errors"
	"net"
)

func GetInterfacesQrData() ([]byte, error) {
	var interfaces []net.Interface
	ifaces, err := net.Interfaces()
	if err != nil {
		return nil, errors.Wrap(err, "list interfaces failed")
	}

	for _, curIf := range ifaces {
		if (curIf.Flags & net.FlagUp) == 0 {
			continue
		}
		if (curIf.Flags & net.FlagLoopback) > 0 {
			continue
		}

		if (curIf.Flags & net.FlagBroadcast) > 0 {
			interfaces = append(interfaces, curIf)
		}
	}

	var rs []net.IP
	for _, curIf := range interfaces {
		addrs, err := curIf.Addrs()
		if err != nil {
			continue
		}

		for _, curAddr := range addrs {
			addr, err := getV4Addr(curAddr)
			if err != nil {
				continue
			}

			rs = append(rs, addr)
		}
	}
	if len(rs) == 0 {
		return nil, errors.New("not enough network interface")
	}

	return addrsToString(rs)
}

func getV4Addr(addr net.Addr) (net.IP, error) {
	ipNet, ok := addr.(*net.IPNet)
	if !ok {
		return nil, errors.New("not ipNet Addr")
	}

	v4 := ipNet.IP.To4()
	if v4 == nil {
		return nil, errors.New("not contain valid v4 addr")
	}

	return v4, nil
}

func addrsToString(addrs []net.IP) ([]byte, error) {
	if len(addrs) > 255 {
		return nil, errors.New("too more interfaces")

	}

	var out = make([]byte, 5 + 1+4*len(addrs))
	copy(out, []byte("esync"))
	out[5] = uint8(len(addrs))

	var pos = 6
	for _, addr := range addrs {
		v4Addr := addr.To4()
		if v4Addr == nil {
			panic("to v4 addr, get nil!")
		}
		for i := 0; i != 4; i++ {
			out[pos+i] = v4Addr[i]
		}
		pos += 4
	}

	return out, nil
}

